package java01_type;

import org.junit.jupiter.api.Test;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.temporal.ChronoUnit;
import java.util.Locale;

import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.MONTHS;

/**
 * https://www.cnblogs.com/yourbatman/p/14324575.html
 *
 * https://www.cnblogs.com/yourbatman/p/14313861.html
 *
 * https://blog.csdn.net/weixin_44711823/article/details/135820463
 *
 * https://blog.csdn.net/yy139926/article/details/124298574
 *
 * https://blog.csdn.net/qq_44749491/article/details/130123065
 *
 * https://blog.csdn.net/nibonnn/article/details/116462747
 *
 * https://blog.csdn.net/qq_36268103/article/details/126838391
 */
public class Test06_LocalDateTime {

    @Test
    public void test_Second_Long_To_LocalDate() {
        long time = 1735874823L;
        LocalDate localDate = LocalDate.ofInstant(Instant.ofEpochSecond(time), ZoneId.of("UTC+8"));
        System.out.println(localDate);
        System.out.println(localDate.getDayOfWeek().getValue());
    }

    @Test
    public void test_Milli_Long_To_LocalDate() {
        long time = 1735874823000L;
        LocalDate localDate = LocalDate.ofInstant(Instant.ofEpochMilli(time), ZoneId.of("UTC+8"));
        System.out.println(localDate);
        System.out.println(localDate.getDayOfWeek().getValue());
    }

    @Test
    public void test_Second_Long_To_LocalDateTime() {
        // 秒Long 转 LocalDateTime
        long time = 1735874823L;
        LocalDateTime localDateTime1 = LocalDateTime.ofInstant(Instant.ofEpochSecond(time), ZoneId.of("UTC+8"));
        LocalDateTime localDateTime2 = LocalDateTime.ofInstant(Instant.ofEpochSecond(time), ZoneOffset.of("+8"));
        System.out.println("1735874823L = " + localDateTime1);
        System.out.println("1735874823L = " + localDateTime2);
    }

    @Test
    public void test_Milli_Long_To_LocalDateTime() {
        // 毫秒Long 转 LocalDateTime
        Long time = 1735874823000L;
        LocalDateTime localDateTime11 = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()); //不推荐
        LocalDateTime localDateTime22 = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.of("UTC+8"));
        LocalDateTime localDateTime33 = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneOffset.of("+8"));

        System.out.println("Long = " + localDateTime11);
        System.out.println("Long = " + localDateTime22);
        System.out.println("Long = " + localDateTime33);
    }

    @Test
    public void test_LocalDate_To_Long() {
        LocalDate date = LocalDate.now();
        System.out.println(date);

        LocalDateTime dateTimeStart = date.atStartOfDay();
        System.out.println(dateTimeStart);

        LocalDateTime dateTimeBegin = date.atTime(LocalTime.MIN);
        System.out.println(dateTimeBegin);

        LocalDateTime dateTimeEnd = date.atTime(LocalTime.MAX);
        System.out.println(dateTimeEnd);

        ZonedDateTime zonedDateTime = date.atStartOfDay(ZoneId.of("UTC+8"));
        System.out.println(zonedDateTime);
    }

    @Test
    public void test_LocalDateTime_To_Long() {
        LocalDateTime now = LocalDateTime.now();

        // LocalDateTime 转 毫秒Long
        long toEpochMilli = now.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        System.out.println(toEpochMilli);

        // LocalDateTime 转 秒Long
        long epochSecond = now.toInstant(ZoneOffset.of("+8")).getEpochSecond();
        System.out.println(epochSecond);
    }

    /**
     * 计算2日期之间相差天数和月数
     */
    @Test
    public void test_Until_Between_LocalDate() {
        LocalDate day1 = LocalDate.of(2014, 9, 12);
        LocalDate day2 = LocalDate.now();

        long untilDays = day1.until(day2, DAYS);
        System.out.println("untilDays = " + untilDays);

        long betweenDays = DAYS.between(day1, day2);
        System.out.println("betweenDays = " + betweenDays);

        long untilMonths = day1.until(day2, MONTHS);
        System.out.println("untilMonths = " + untilMonths);

        long betweenMonths = MONTHS.between(day1, day2);
        System.out.println("betweenMonths = " + betweenMonths);

        // Period类:年月日【单独】计算的，很少有这样的需求
        Period period = Period.between(day1, day2);
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
    }

    @Test
    public void test_Until_Between_LocalDateTime() {
        // 时间的比较
        LocalDateTime from = LocalDateTime.now();
        LocalDateTime to = from.plusHours(480);
        System.out.println(from.isBefore(to));

        //获取相差的秒数
        long betweenSeconds = ChronoUnit.SECONDS.between(from, to);
        long betweenMinutes = ChronoUnit.MINUTES.between(from, to);
        long betweenHours = ChronoUnit.HOURS.between(from, to);
        long betweenDays = ChronoUnit.DAYS.between(from, to);
        System.out.println(betweenSeconds);
        System.out.println(betweenMinutes);
        System.out.println(betweenHours);
        System.out.println(betweenDays);

        Period period = Period.between(from.toLocalDate(), to.toLocalDate());
        System.out.println("period.getYears() = " + period.getYears());
        System.out.println("period.getMonths() = " + period.getMonths());
        System.out.println("period.getDays() = " + period.getDays());

        Duration duration = Duration.between(from, to);
        System.out.println("duration.toDays() = " + duration.toDays());
        System.out.println("duration.toHours() = " + duration.toHours());
        System.out.println("duration.toMinutes() = " + duration.toMinutes());
        System.out.println("duration.getSeconds() = " + duration.getSeconds());
    }

    @Test
    public void String_To_LocalDate() {

        // 字符串转LocalDate
        String dateString = "2023-05-04";
        LocalDate localDate = LocalDate.parse(dateString);
        System.out.println(localDate);

        // 使用特定格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        LocalDate localDate2 = LocalDate.parse("2023/05/04", formatter);
        System.out.println(localDate2);
    }

    @Test
    public void LocalDate_To_String() {
        LocalDate now = LocalDate.now();
        System.out.println(now);

        // 使用特定格式化
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
        // LocalDate转String
        System.out.println(now.format(formatter));
    }

    /**
     * String 转 LocalDateTime
     */
    @Test
    public void String_To_LocalDateTime() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime LocalTime = LocalDateTime.parse("2023-03-29 19:19:46", formatter);
        System.out.println("String类型的时间转成LocalDateTime：" + LocalTime);
    }

    /**
     * LocalDateTime 转 String
     */
    @Test
    public void LocalDateTime_To_String() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String timeFormat = now.format(formatter);
        System.out.println(timeFormat);
    }

    @Test
    public void testDisplayName() {
        Long time = 1726125533000L;
        LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.of("UTC+8"));
        System.out.println(localDateTime);
        System.out.println(localDateTime.getDayOfWeek().getValue());

        //JDK 1.8支持
        System.out.println(localDateTime.getMonth().getDisplayName(TextStyle.FULL, Locale.CHINA));
        System.out.println(localDateTime.getMonth().getDisplayName(TextStyle.SHORT, Locale.CHINA));
        System.out.println(localDateTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINA));
        System.out.println(localDateTime.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.CHINA));

        System.out.println(localDateTime.getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
        System.out.println(localDateTime.getMonth().getDisplayName(TextStyle.SHORT, Locale.ENGLISH));
        System.out.println(localDateTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.ENGLISH));
        System.out.println(localDateTime.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.ENGLISH));

        System.out.println(localDateTime.getMonth().getDisplayName(TextStyle.FULL, Locale.US));
        System.out.println(localDateTime.getMonth().getDisplayName(TextStyle.SHORT, Locale.US));
        System.out.println(localDateTime.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.US));
        System.out.println(localDateTime.getDayOfWeek().getDisplayName(TextStyle.SHORT, Locale.US));
    }
}
